package com.zyy.java8.samples.misc;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @author zhangyiying
 * @ClassName: CheckedFunctions
 * @Description:
 * @date 2022/2/8 14:27
 */
public final class CheckedFunctions {
    @FunctionalInterface
    public interface CheckedConsumer<T>{
        void accept(T input) throws Exception;
    }

    @FunctionalInterface
    public interface CheckedPredicate<T>{
        boolean test(T input) throws Exception;
    }

    @FunctionalInterface
    public interface CheckedFunction<F, T>{
        T apply(F input) throws Exception;
    }


    /**
     * 返回一个方法 可以检测异常，并重新抛出为运行时异常
     * @param checkedFunction
     * @param <F>
     * @param <T>
     * @return
     */
    public static <F, T> Function<F, T> function(CheckedFunction<F, T> checkedFunction){
        return input -> {
            try {
                return checkedFunction.apply(input);
            } catch (Exception e) {
                if (e instanceof RuntimeException){
                    throw  (RuntimeException)e;
                }
                throw  new RuntimeException(e);
            }
        };
    }


    /**
     * 返回一个断言 可以检测异常，并重新抛出为运行时异常
     * @param checkedPredicate
     * @param <T>
     * @return
     */
    public static <T> Predicate<T> predicate(CheckedPredicate<T> checkedPredicate){
        return input -> {
            try {
                return checkedPredicate.test(input);
            } catch (Exception e) {
                if (e instanceof RuntimeException){
                    throw (RuntimeException)e;
                }
                throw new RuntimeException(e);
            }
        };
    }


    /**
     * 返回一个消费者 可以检查异常，并重新抛出为运行时异常
     * @param checkedConsumer
     * @param <T>
     * @return
     */
    public static <T> Consumer<T> consumer(CheckedConsumer<T> checkedConsumer){
        return input -> {
            try {
                checkedConsumer.accept(input);
            } catch (Exception e) {
                if (e instanceof  RuntimeException){
                    throw (RuntimeException)e;
                }
                throw new RuntimeException(e);
            }
        };
    }

}
